package com.pantuo.sys.service.impl;

import com.pantuo.common.exception.ServiceException;
import com.pantuo.common.utils.DataTablePage;
import com.pantuo.common.utils.TableRequest;
import com.pantuo.sys.dao.CommonDao;
import com.pantuo.sys.service.CommonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import sun.net.www.http.HttpClient;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service

public class CommonServiceImpl implements CommonService {

    @Autowired
    private CommonDao commonDao;

    /**
     * 通用删除
     *
     * @param className
     * @param id
     * @return
     */
    @Override
    public Boolean delById(String className, Integer... id) {
        System.out.println("className：" + className);
        //判断表名是否为空
        if (className == null || className == "") {
            throw new ServiceException("表名不能为空");
        }
        int row = commonDao.deleteObject(className, id);
        if (row == 0) {
            throw new ServiceException("该记录可能已被删除");
        }
        return true;
    }

    /**
     * 通用添加与更新，增加表的列名查询，可以解决项目后期添加字段问题
     *
     * @param params
     */
    @Override
    public void saveOrUpdate(Map<String, Object> params) {
        //获取表名
        String className = (String) params.get("className");
        //判断表名是否为空
        if (className == null || className == "") {
            throw new ServiceException("表名不能为空");
        }
        //查询表中列的集合
        List<String> columnNames = commonDao.findColumnNames(className);
        System.out.println("表中列集合：" + columnNames);
        Set<String> keySet = params.keySet();
        for (String key : keySet) {
            //这里做判断防止将传过来的表名(className)添加为表的列名
            if (key.endsWith("_i") || key.endsWith("_s") || key.endsWith("dt") || key.endsWith("_d")) {
                //遍历map的键，发现表中没有该列时增加该列
                if (!columnNames.contains(key)) {
                    System.out.println("表中不包含：" + key);
                    commonDao.addColumn(className, key);
                }
            }
        }
        //传过来的字段和数据库的字段比对完后进行添加或更新操作
        if (params.get("id") != null) {
            params.remove("created_dt");
            params.remove("updated_dt");
            commonDao.updateObject(params);
        } else {
            if (params.size() == 1) {
                throw new ServiceException("所有字段都为空，不允许保存操作");
            }
            commonDao.insertObject(params);
        }

    }


    /**
     * 通用分页与查询(查询条件任意)
     *
     * @param request
     * @param className
     * @return
     */
    @Override
    public PageImpl<Object> getModelList(TableRequest request, String className) {
        //判断表名是否为空
        if (className == null || className == "") {
            throw new ServiceException("表名不能为空");
        }
        //获取起始索引
        int start = request.getStart();
        //获取页面大小
        int length = request.getLength();
        //获取查询条件，用map封装
        Map<String, String> filter = request.getFilter();
        //获取排序字段和排序规则 asc or desc
        List<Map<String, String>> orderList = request.getOrder();
        //一页数据的集合
        List<Map<String, Object>> commonRecords = null;
        //将className作为参数到数据库查找sql语句
        List<String> sqlList = commonDao.findSql(className);
        //得到sqlList的几个大小
        int sqlListSize = sqlList.size();
        //判断sqlList的集合是否为空
        String tableName1 = sqlListSize == 0 ? className : sqlList.get(0);
        String tableName2 = sqlListSize == 0 ? className : sqlList.get(1);
        //如果排序条件为空则默认按照创建时间排序(最后创建的用户排在最前面)
        if (orderList == null) {
            //如果sqlListSize为0则是单表查询获取总数，否则为多表查询获取总数
            Long total = sqlListSize == 0 ? commonDao.getTotal(filter, tableName2) : commonDao.getTotalByJoin(filter, tableName2);
            if (total == 0) {
                throw new ServiceException("暂无记录");
            }
            //如果sqlListSize为0则走单表获取数据，否则走多表查询获取数据
            commonRecords = sqlListSize == 0 ?
                    commonDao.findAllObjects(filter, null, start, length, tableName1) : commonDao.findAllObjectsByJoin(filter, null, start, length, tableName1);
            return new DataTablePage(new PageImpl<>(commonRecords, PageRequest.of(request.getPage(), length), total));
        }
        //如果排序不为空
        Map<String, String> orderMap = orderList.get(0);

        for (Map<String, String> map : orderList) {

        }
        Long total = sqlListSize == 0 ? commonDao.getTotal(filter, tableName2) : commonDao.getTotalByJoin(filter, tableName2);
        //如果sqlListSize为0则是单表查询获取总数，否则为多表查询获取总数
        if (total == 0) {
            throw new ServiceException("暂无记录");
        }
        int page = request.getPage();
        //如果sqlListSize为0则走单表获取数据，否则走多表查询获取数据
        commonRecords = sqlListSize == 0 ?
                commonDao.findAllObjects(filter, orderList, start, length, tableName1) : commonDao.findAllObjectsByJoin(filter, null, start, length, tableName1);
        return new DataTablePage(new PageImpl<>(commonRecords, PageRequest.of(request.getPage(), length), total));
    }

    /**
     * 通用根据字段删除
     *
     * @param dByField
     * @param value
     * @param className
     * @return
     */
    @Override
    public Boolean delByField(String dByField, String value, String className) {
        //判断表名是否为空
        if (className == null || className == "") {
            throw new ServiceException("表名不能为空");
        }
        Boolean flag = commonDao.deleteByField(dByField, value, className);
        if (flag == false) {
            throw new ServiceException("该记录可能已被删除");
        }
        return flag;
    }

    /**
     * 通用根据id查询
     *
     * @param id
     * @param className
     * @return
     */
    @Override
    public Map<String, Object> queryById(String id, String className) {
        //判断表名是否为空
        if (className == null || className == "") {
            throw new ServiceException("表名不能为空");
        }
        return commonDao.findObjectById(id, className);
    }


}
